//+------------------------------------------------------------------+
//|                                  Trend_Hedge_Strategy.mq4        |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Edison"
#property version   "1.00"
#property strict



//--- 输入参数
input int      FastEMA = 5;         // 快速EMA周期
input int      MediumEMA = 20;      // 中期EMA周期
input int      SlowEMA = 50;        // 慢速EMA周期
input int      ADX_Period = 14;     // ADX周期
input double   ADX_Threshold = 25;  // ADX趋势阈值
input int      RSI_Period = 14;     // RSI周期
input int      CCI_Period = 20;     // CCI周期
input int      FractalBars = 3;     // 分形验证K线数

 input double   LotSize=0.01;        // 基础手数
 input double   HedgeTrigger=1.1;   // 对冲触发阈值(百分比)
 input int      MaxOrders=20;        // 最大订单数
 input double   StopLoss=300;       // 止损点数
 input double   TakeProfit=600;     // 止盈点数

//--- 全局变量
int    trendDirection = 0;         // 当前趋势方向
double hedgeThreshold;             // 动态对冲阈值
datetime lastTradeTime = 0;

//+------------------------------------------------------------------+
//| 自定义趋势强度枚举类型                                           |
//+------------------------------------------------------------------+
enum ENUM_TREND_STRENGTH {
   TREND_NO_POWER,     // 无趋势
   TREND_WEAK,         // 弱趋势
   TREND_MEDIUM,       // 中等趋势
   TREND_STRONG        // 强趋势
};

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   hedgeThreshold = HedgeTrigger * _Point * 100;
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 分形结构验证函数                                                 |
//+------------------------------------------------------------------+
bool CheckFractalStructure(int barsToCheck,bool emaBullish,bool emaBearish)
{
   bool upperFractal = false;
   bool lowerFractal = false;
   
   // 检测最近的分形
   for(int i=3; i<=barsToCheck+3; i++) {
      if(iFractals(NULL,0,MODE_UPPER,i) != 0) upperFractal = true;
      if(iFractals(NULL,0,MODE_LOWER,i) != 0) lowerFractal = true;
   }
   
   // 上涨趋势需要突破上方分形
   if(emaBullish && Close[0] > iFractals(NULL,0,MODE_UPPER,3)) return true;
   
   // 下跌趋势需要突破下方分形
   if(emaBearish && Close[0] < iFractals(NULL,0,MODE_LOWER,3)) return true;
   
   return false;
}
//+------------------------------------------------------------------+
//| 趋势判断函数                                                     |
//+------------------------------------------------------------------+
int CheckTrend()
{
    //--- 获取指标数据
   double emaFast = iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,0);
   double emaMed = iMA(NULL,0,MediumEMA,0,MODE_EMA,PRICE_CLOSE,0);
   double emaSlow = iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,0);
   
   double adxMain = iADX(NULL,0,ADX_Period,PRICE_CLOSE,MODE_MAIN,0);
   double plusDI = iADX(NULL,0,ADX_Period,PRICE_CLOSE,MODE_PLUSDI,0);
   double minusDI = iADX(NULL,0,ADX_Period,PRICE_CLOSE,MODE_MINUSDI,0);
   
   double rsi = iRSI(NULL,0,RSI_Period,PRICE_CLOSE,0);
   double cci = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,0);
   
   //--- 趋势方向判断
   bool emaBullish = (emaFast > emaMed) && (emaMed > emaSlow);
   bool emaBearish = (emaFast < emaMed) && (emaMed < emaSlow);
   
   //--- 趋势强度分析
   ENUM_TREND_STRENGTH strength = TREND_NO_POWER;
   if(adxMain >= ADX_Threshold) {
      double diDiff = MathAbs(plusDI - minusDI);
      if(diDiff > 15) strength = TREND_STRONG;
      else if(diDiff > 8) strength = TREND_MEDIUM;
      else strength = TREND_WEAK;
   }
   
   //--- 价格结构验证
   bool priceConfirmed = CheckFractalStructure(FractalBars,emaBullish,emaBearish);
   
   //--- 动量指标过滤
   bool momentumOK = false;
   if(emaBullish && rsi < 70 && cci > 0) momentumOK = true;
   if(emaBearish && rsi > 30 && cci < 0) momentumOK = true;
   
   //--- 综合判断
   if(emaBullish && strength >= TREND_MEDIUM && priceConfirmed && momentumOK) {
     return 1;
      // 触发买入逻辑
   }
   else if(emaBearish && strength >= TREND_MEDIUM && priceConfirmed && momentumOK) {
      return -1;
      // 触发卖出逻辑
   }
   else {
     return 0;
   }
}

//+------------------------------------------------------------------+
//| 执行对冲操作                                                     |
//+------------------------------------------------------------------+
void HedgeOperation(int direction)
{

   double price = (direction == 1) ? Ask : Bid;
   int ticket = OrderSend(Symbol(), direction==1?OP_BUY:OP_SELL, HedgeTrigger*LotSize, price, 3, 0, 0, "Hedge", 0, clrNONE);
   if(ticket > 0)
   {
      double sl = (direction == 1) ? price - StopLoss*_Point : price + StopLoss*_Point;
      double tp = (direction == 1) ? price + TakeProfit*_Point : price - TakeProfit*_Point;
      OrderModify(ticket, OrderOpenPrice(), sl, tp, 0);
   }
}

//+------------------------------------------------------------------+
//| 动态风险管理                                                    |
//+------------------------------------------------------------------+
bool RiskManagement()
{
   double totalProfit = 0;
   int buyCnt = 0, sellCnt = 0;
   for(int i=0; i<OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS))
      {
         totalProfit += OrderProfit();
         if(OrderType() == OP_BUY) buyCnt++;
         if(OrderType() == OP_SELL) sellCnt++;
      }
   }
   
   // 对冲触发条件
   if(totalProfit < -hedgeThreshold && MathAbs(buyCnt - sellCnt) >= 2)
   {
      int newDirection = (buyCnt > sellCnt) ? OP_SELL : OP_BUY;
      HedgeOperation(newDirection);
      return true;
   }
   return false;
}

//+------------------------------------------------------------------+
//| 主交易逻辑                                                      |
//+------------------------------------------------------------------+
void ExecuteTrading()
{
   // 趋势方向判定
   int newTrend = CheckTrend();
   
   // 趋势反转时清仓
   if(newTrend != trendDirection && newTrend != 0)
   {
      CloseAllOrders();
      trendDirection = newTrend;
   }
   
   // 执行趋势交易
   if(OrdersTotal() < MaxOrders && newTrend != 0)
   {
      int ticket = OrderSend(Symbol(), newTrend==1?OP_BUY:OP_SELL, LotSize, 
                           newTrend==1?Ask:Bid, 3, 0, 0, "Trend", 0, clrNONE);
                           
      if(ticket > 0)
      {
         double sl = (newTrend == 1) ? Bid - StopLoss*_Point : Ask + StopLoss*_Point;
         double tp = (newTrend == 1) ? Bid + TakeProfit*_Point : Ask - TakeProfit*_Point;
         OrderModify(ticket, OrderOpenPrice(), sl, tp, 0);
      }
   }
}

//+------------------------------------------------------------------+
//| 清空所有订单                                                     |
//+------------------------------------------------------------------+
void CloseAllOrders()
{
   for(int i=0; i<=OrdersTotal()-1; i++)
   {
      if(OrderSelect(i, SELECT_BY_POS,MODE_TRADES))
      {
         string zhushi = OrderComment();
         Print("11===zhushi");
         Print(zhushi);
          Print("===zhushi");
         if(OrderType() == OP_BUY) OrderClose(OrderTicket(), OrderLots(), Bid, 3);
         if(OrderType() == OP_SELL) OrderClose(OrderTicket(), OrderLots(), Ask, 3);
      }else{
         Print("Error selecting order: ", GetLastError());
      }
   }
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   if(Time[0] == lastTradeTime) return;
   // 每根新K线执行一次
   lastTradeTime = Time[0];
   RiskManagement();    // 先执行风险管理
   ExecuteTrading();    // 再执行趋势交易
}
//+------------------------------------------------------------------+